This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

library(tidyplots)

Attaching package: ‘tidyplots’

The following object is masked from ‘package:ggpubr’:

    gene_expression

>>>> Figure 1: plots of TE experiment data - read counts and read depths

Read-in data

#ATCC genomes updated version
#October 2024

#viral load vs read count normalised using different methods, comparing deduplicated and non-deduplicated
#use bowtie2 data

####read counts/normalised read counts####

#metadata

metadata <- read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

Format data

Make plots

plot just the two lefthand panels from the original figure

plot viral read counts (non normalised)

Final plot

——————–

Figure S1

Read depths

depth_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )
Rows: 95 Columns: 12── Column specification ─────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (5): virus, Sample_id, Background, mapper, type
dbl (7): Viral load, mean_depth, median_depth, min, max, LQ, UQ
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Make plots


read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10() +
  ylab("Log(mean read depth)")

#ggsave("figures/compare_spike_ins_atcc/mean_depth.pdf",width=8,height=6)

Final plot

ggarrange(
  read_count,
  read_count_norm1,
  read_count_norm2,
  read_depths,
  nrow = 2,
  ncol = 2,
  common.legend = TRUE,
  align = "hv"
)
Error: object 'read_count' not found

——————–

Figure S2

Reaed-in data / Make plots

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

####compare library capture pool####

cols3 <- c("#228833", "#AA3377")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

metadata3 <- 
  metadata |>
  select(Sample.ID, Pool.for.sequencing) |>
  rename(Sample_id = Sample.ID) |>
  rename(Pool = Pool.for.sequencing)

counts_pool <- left_join(counts_reads_norm, metadata3, by = "Sample_id")

Make plots


pool_readcounts <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(x = virus, y = log(matched))) +
  geom_boxplot() +
  facet_grid(Pool ~ type) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (Viral Reads)") + xlab("Viral load (copies / ml)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

pool_counts_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (Viral Reads)") + xlab("Viral load (copies / ml)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

pool_readcounts_norm <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(x = virus, y = log(norm_counts1))) +
  geom_boxplot() +
  facet_grid(Pool ~ type) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log(viral reads/cleaned reads)") +  xlab("Viral load (copies / ml)")

pool_norm1_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log(viral reads/cleaned reads)") +   xlab("Viral load (copies / ml)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

pool_readcounts_norm2 <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(x = virus, y = log(norm_counts2))) +
  geom_boxplot() +
  facet_grid(Pool ~ type) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log(viral reads/cleaned reads/genome length)") + xlab("Viral load (copies / ml)")


pool_norm2_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log(viral reads/cleaned reads/genome length)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
  xlab("Viral load (copies / ml)")


#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- 
  left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

depths_pool <- left_join(depths_reads, metadata3, by = "Sample_id")

pool_readdepths <- 
  depths_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(x = virus, y = log(mean_depth))) +
  geom_boxplot() +
  facet_grid(Pool ~ type) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_text(angle = 45, hjust = 1),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (mean read depth)") + xlab("Viral load (copies / ml)")

pool_depths_sum <- 
  depths_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log(mean_depth),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (mean read depth)") +
  xlab("Viral load (copies / ml)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

Final plot

ggarrange(
  pool_counts_sum,
  pool_norm1_sum,
  pool_norm2_sum,
  pool_depths_sum,
  nrow = 2,
  ncol = 2,
  common.legend = TRUE,
  align = "hv"
)

#ggsave("figures/compare_spike_ins_atcc/pool_compare_viruses_sum.png",width=10,height=7)

#ggsave("figures/manuscript_figures_pdf/FigureS2.pdf",width=10,height=7)

——————–

Figure S3


##plots of read counts and viral read counts
#November 2024

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import read count files

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

#import viral reads mapped (to calculate proportions)

viral_reads_dedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_dedup_atcc_ref_20241108.csv",
    header = TRUE
  )

viral_reads_nodedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_nodedup_atcc_ref_20241108.csv",
    header = TRUE
  )

cols2 <- c("#BB5566", "#004488")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

reads_metadata_dedup <-
  left_join(counts_dedup_bt, metadata2, by = "Sample_id")

reads_viral_dedup <-
  left_join(reads_metadata_dedup, viral_reads_dedup, by = "Sample_id")

reads_metadata_nodedup <-
  left_join(counts_nodedup_bt, metadata2, by = "Sample_id")

reads_viral_nodedup <-
  left_join(reads_metadata_nodedup, viral_reads_nodedup, by = "Sample_id")

reads_viral_all <- rbind(reads_viral_dedup, reads_viral_nodedup)


reads_plot <- 
  reads_viral_all |>
  group_by(Background, Sample_id, Viral.load, type) |>
  summarise(
    total_reads = (QC_reads * 2),
    viral_reads = total_virus_reads,
    ATCC_reads = sum(matched),
    prop_ATCC = ATCC_reads / total_reads,
    prop_viral = total_virus_reads / total_reads,
    diff = viral_reads - ATCC_reads
  ) |>
  unique()

Make plots

Final plot

——————–

Figure S4

Make plots

####read counts/depths split by background####

#change labels in facet plots

facet_names_bg <- c(
  "dedup_TE" = "Deduplicated",
  "nodedup_TE" = "Non-Deduplicated",
  "p2" = "P1",
  "p8" = "P2"
)

#break down by Background x virus

background_counts_reads <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels =
      c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
      )
  ) +
  scale_x_log10(labels = scales::label_log()) +
  ylab("Log(Viral Reads)")

backgrounds_counts_reads_norm <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log(norm_counts1),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_bw() +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log()) +
  ylab("Log(viral reads/cleaned reads)")

backgrounds_counts_reads_norm2 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(labels = scales::label_log()) +
  ylab("Log(viral reads/cleaned reads/genome length)")

background_read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray"),
    axis.title.y = element_text(size = 10),
    legend.title = element_blank()
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log()) +
  ylab("Log(mean read depth)")

Final plot

——————–

Figure S5 - linear model

Read-in data

Format data


depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  ,
  .default = "RNA"
  ))

####linear model for spike in viruses - mean read depth####

depths_reads_sub <- depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  mutate(log_depth = log(mean_depth)) |>
  mutate(log_viral_load = log10(Viral.load))

#inspect data
hist(depths_reads_sub$mean_depth)
hist(depths_reads_sub$Viral.load)
hist(depths_reads_sub$log_depth)
hist(depths_reads_sub$log_viral_load)

summary(depths_reads_sub$log_depth)
summary(depths_reads_sub$log_viral_load)

model

lm_tidy <- 
  do.call(rbind.data.frame, tidy(list_models))
Error: No tidy method recognized for this list.

——————–

>>> Figure 2: plots of TE experiment data - genome coverage & per site coverage

Read-in data


#plots of TE experiment data - genome coverage & per site coverage
#also separated by viruses
#ATCC genomes updated version
#October 2024

#use bowtie2 data

####genome coverage####

unzip(zipfile = "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv.zip", exdir = "data_TE/")

unzip(zipfile = "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv.zip", exdir = "data_TE/")

dedup_per_site <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv"
  )


nodedup_per_site <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )

file.remove("data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv")

file.remove( "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv")

#add length column from read depth file to per site file

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- 
  metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files

#deduplicated and non-deduplicated

counts_dedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv"
  )

counts_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

Format data

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- 
  counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

lengths <- 
  counts_reads_norm |>
  select(virus, length) |>
  distinct()

#calculate genome coverage

persite_coverage_dedup <- 
  dedup_per_site |>
  rename(Viral.load = `Viral load`) |>
  group_by(Sample_id, virus, Viral.load, Background, type) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)

persite_coverage_nodedup <- 
  nodedup_per_site |>
  rename(Viral.load = `Viral load`) |>
  group_by(Sample_id, virus, Viral.load, Background, type) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)

persite_coverage_both <-
  rbind(persite_coverage_dedup, 
        persite_coverage_nodedup)

coverage_labels <- c("0" = "Control",
                     "100" = "10^{2}",
                     "1000" = "10^{3}",
                     "10000" = "10^{5}",
                     "dedup_TE" = "Deduplicated",
                     "nodedup_TE"= "Non-Deduplicated")

coverage_labels2 <- c("0" = "Control",
                      "100" = "10^{2}",
                      "1000" = "10^{3}",
                      "10000" = "10^{5}")

Make plots

Final plot

——————–

——————–

Figure S6


persite_both <- rbind(dedup_per_site, nodedup_per_site)

persite_reads <- left_join(persite_both, metadata2, by = "Sample_id")

persite_norm <- persite_reads |>
  mutate(norm_cov = coverage / QC_reads)

coverage_labels3 <-c("100" = "1e+02",
                    "1000" = "1e+03",
                    "100000" = "1e+05",
                    "p2" = "P1",
                    "p8"= "P2")

persite_norm$`Viral load` <- 
  factor(persite_norm$`Viral load`, 
         labels = c("0",
                    "10^{2}", 
                    "10^{3}",
                    "10^{5}"))


persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_respiratory_syncytial_virus") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id, label = label_parsed) +
  ylab("Log(Coverage)") +
  ggtitle("Human RSV (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("P1", "P2"))

Final plot

#ggsave("figures/manuscript_figures_pdf/FigureS5.pdf",width=10,height=8)

——————–

Figure S7


persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Zika_virus") |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id) +
  ylab("Log(Coverage)") +
  ggtitle("Zika virus (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
  theme_bw() +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("P1", "P2"))

#ggsave("figures/manuscript_figures_pdf/FigureS6.pdf",width=10,height=8)

——————–

Figure S8

persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_adenovirus_40") |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id) +
  ylab("Log(Coverage)") +
  ggtitle("Human Adenovirus (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
  theme_bw() +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("P1", "P2"))

#ggsave("figures/manuscript_figures_pdf/FigureS7.pdf",width=20,height=18)

——————–

Figure S9

persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_betaherpesvirus") |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_polygon() +
  facet_wrap(Viral.load ~ Sample_id) +
  ylab("Log(Coverage)") +
  ggtitle("Human Betaherpesvirus (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
  theme_bw() +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("P1", "P2"))

#ggsave("figures/compare_spike_ins_atcc/HBHV_coverage_test.pdf",width=20,height=18)

——————–

Figure S10

#have to do these differently due to segmentation

FLU_ME1 <- persite_norm |>
  filter(virus == "Influenza_B_virus") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Log(Coverage)") +
  ggtitle("Influenza B virus (Background 1 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_bw() +
  scale_y_log10() +
  scale_fill_manual(values = cols4,
                    labels = c("1e+02", "1e+03", "1e+05"))

FLU_ME2 <- persite_norm |>
  filter(virus == "Influenza_B_virus") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p8") |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Log(Coverage)") +
  ggtitle("Influenza B virus (Background 2 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_bw() +
  scale_y_log10() +
  scale_fill_manual(values = cols4,
                    labels = c("1e+02", "1e+03", "1e+05"))

ggarrange(FLU_ME1, FLU_ME2, ncol = 2, common.legend = TRUE)

#ggsave("figures/manuscript_figures_pdf/FigureS9.pdf",width=20,height=18)

——————–

Figure S11


REO_ME1 <- persite_norm |>
filter(virus == "Mammalian_orthoreovirus3") |>
filter(type == "dedup_TE") |>
filter(Background == "p2") |>
ggplot(aes(
x = site,
y = coverage,
fill = as.character(Viral.load)
)) +
geom_col() +
facet_grid(seg ~ Sample_id) +
ylab("Log(Coverage)") +
ggtitle("Mammalian orthoreovirus 3 (Background 1 deduplicated)") +
guides(fill = guide_legend(title = "Viral load")) +
theme_bw() +
scale_y_log10() +
scale_fill_manual(values = cols4,
labels = c("1e+02", "1e+03", "1e+05"))

REO_ME2 <- persite_norm |>
filter(virus == "Mammalian_orthoreovirus3") |>
filter(type == "dedup_TE") |>
filter(Background == "p8") |>
ggplot(aes(
x = site,
y = coverage,
fill = as.character(Viral.load)
)) +
geom_col() +
facet_grid(seg ~ Sample_id) +
ylab("Log(Coverage)") +
ggtitle("Mammalian orthoreovirus 3 (Background 2 deduplicated)") +
guides(fill = guide_legend(title = "Viral load")) +
theme_bw() +
scale_y_log10() +
scale_fill_manual(values = cols4,
labels = c("1e+02", "1e+03", "1e+05"))

ggarrange(REO_ME1, REO_ME2, ncol = 2, common.legend = TRUE)

#ggsave("figures/manuscript_figures_pdf/FigureS10.pdf",width=20,height=18)

——————–

>>>> Figure 3: all viruses - target and off target

Read-in data


# read in metadata

metadata <-
  read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <-
  metadata |>
  select(
    Sample.ID,
    Background.sample,
    Viral.load,
    Number.of.read.pairs..quality.adaptor.trimmed.
  ) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import viral reads mapped (to calculate proportions)

viral_reads_dedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_dedup_atcc_ref_20241108.csv",
    header = TRUE
  )

viral_reads_nodedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_nodedup_atcc_ref_20241108.csv",
    header = TRUE
  )

#import contingency tables

contingency_dedup <-
  read.csv(
    "data_TE/contingency_table_mapped_virus_reads_per_family_genus_sample_dedup_atcc_ref_20241106.csv",
    header = TRUE
  )

contingency_nodedup <-
  read.csv(
    "data_TE/contingency_table_mapped_virus_reads_per_family_genus_sample_nodedup_atcc_ref_20241106.csv",
    header = TRUE
  )

contaminants <-
  c("Betacoronavirus", "Alphainfluenzavirus", "Gammaretrovirus")

Format data


# pivot longer  
dedup_long <-
  contingency_dedup |>
  filter(!genus %in% contaminants) |>
  filter(genus != "NA") |>
  pivot_longer(cols = A:P,
               names_to = "Sample_id",
               values_to = "count") |>
  mutate(
    target = case_when(
      genus == "Cyclovirus" ~ "off_target",
      genus == "Cardiovirus" ~ "off_target",
      genus == "Kobuvirus" ~ "off_target",
      .default = "on_target"
    )
  ) |>
  mutate(genome_structure = case_when((genus == "Mastadenovirus" |
                                         genus == "Cytomegalovirus") ~ "DNA",
                                      .default = "RNA"
  ))

no_dedup_long <- contingency_nodedup |>
  filter(!genus %in% contaminants) |>
  filter(genus != "NA") |>
  pivot_longer(cols = A:P,
               names_to = "Sample_id",
               values_to = "count") |>
  mutate(
    target = case_when(
      genus == "Cyclovirus" ~ "off_target",
      genus == "Cardiovirus" ~ "off_target",
      genus == "Kobuvirus" ~ "off_target",
      .default = "on_target"
    )
  ) |>
  mutate(genome_structure = case_when((genus == "Mastadenovirus" |
                                         genus == "Cytomegalovirus") ~ "DNA",
                                      .default = "RNA"
  ))

metadata_dedup <- left_join(dedup_long, metadata2, by = "Sample_id")

dedup_viral_reads <-
  left_join(metadata_dedup, viral_reads_dedup, by = "Sample_id") |>
  mutate(total_reads = QC_reads * 2) |>
  mutate(prop_total = count / total_reads) |>
  mutate(prop_viral = count / total_virus_reads)

metadata_no_dedup <- left_join(no_dedup_long, metadata2, by = "Sample_id")

nodedup_viral_reads <-
  left_join(metadata_no_dedup, viral_reads_nodedup, by = "Sample_id") |>
  mutate(total_reads = QC_reads * 2) |>
  mutate(prop_total = count / total_reads) |>
  mutate(prop_viral = count / total_virus_reads)

Make plots

Dedup – viral reads, prop all reads, and prop viral reads

Final plot

—-nodedup results —-

——————–

LS0tCnRpdGxlOiAidGFyZ2V0X29mZnRhcmdldCIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KIyNhbGwgdmlydXNlcyAtIHRhcmdldCBhbmQgb2ZmIHRhcmdldAoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHRpZHlwbG90cykKbGlicmFyeShnZ3RoZW1lcykKCmBgYAoKCiMjID4+Pj4gRmlndXJlIDE6IHBsb3RzIG9mIFRFIGV4cGVyaW1lbnQgZGF0YSAtIHJlYWQgY291bnRzIGFuZCByZWFkIGRlcHRocwoKIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KI0FUQ0MgZ2Vub21lcyB1cGRhdGVkIHZlcnNpb24KI09jdG9iZXIgMjAyNAoKI3ZpcmFsIGxvYWQgdnMgcmVhZCBjb3VudCBub3JtYWxpc2VkIHVzaW5nIGRpZmZlcmVudCBtZXRob2RzLCBjb21wYXJpbmcgZGVkdXBsaWNhdGVkIGFuZCBub24tZGVkdXBsaWNhdGVkCiN1c2UgYm93dGllMiBkYXRhCgojIyMjcmVhZCBjb3VudHMvbm9ybWFsaXNlZCByZWFkIGNvdW50cyMjIyMKCiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0gcmVhZC5jc3YoIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwgaGVhZGVyID0gVFJVRSkKCm1ldGFkYXRhMiA8LSBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGNvdW50IGZpbGVzCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX25vZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX2J0X2FsbCA8LSByYmluZChjb3VudHNfZGVkdXBfYnQsIGNvdW50c19ub2RlZHVwX2J0KQoKY291bnRzX3JlYWRzIDwtIGxlZnRfam9pbihjb3VudHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgojbm9ybWFsaXNlIGJ5IGJvdGggcmF3IHJlYWQgY291bnQgYW5kIGdlbm9tZSBsZW5ndGggLSBzaG91bGQgYmUgdGhlIHNhbWUgYXMgbWVhbiByZWFkIGRlcHRoCgpjb3VudHNfcmVhZHNfbm9ybSA8LSBjb3VudHNfcmVhZHMgfD4KICBtdXRhdGUobm9ybV9jb3VudHMxID0gbWF0Y2hlZCAvIFFDX3JlYWRzKSB8PgogIG11dGF0ZShub3JtX2NvdW50czIgPSBtYXRjaGVkIC8gUUNfcmVhZHMgLyBsZW5ndGgpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMyA9IG1hdGNoZWQgLyBsZW5ndGgpIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKAogICAgdmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiIHwKICAgICAgdmlydXMgPT0gIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIKICApIH4gIkROQSIsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpgYGAKCgojIyMgRm9ybWF0IGRhdGEKYGBge3J9CiNjaGFuZ2UgbGFiZWxzIGluIGZhY2V0IHBsb3RzCgpmYWNldF9uYW1lcyA8LSBjKCJkZWR1cF9URSIgPSAiRGVkdXBsaWNhdGVkIiwKICAgICAgICAgICAgICAgICAibm9kZWR1cF9URSIgPSAiTm9uLURlZHVwbGljYXRlZCIpCgpjb2xzIDwtIGMoIiM0NDc3QUEiLAogICAgICAgICAgIiM2NkNDRUUiLAogICAgICAgICAgIiMyMjg4MzMiLAogICAgICAgICAgIiNDQ0JCNDQiLAogICAgICAgICAgIiNFRTY2NzciLAogICAgICAgICAgIiNBQTMzNzciKQpgYGAKCiMjIyBNYWtlIHBsb3RzCmBgYHtyfQoKI3Bsb3QgdmlyYWwgcmVhZCBjb3VudHMgKG5vbiBub3JtYWxpc2VkKQoKcmVhZF9jb3VudCA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cobWF0Y2hlZCksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHlsYWIoIkxvZyhWaXJhbCBSZWFkcykiKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL3JlYWRfY291bnRzLnBkZiIsd2lkdGg9OCxoZWlnaHQ9NikKCiNub3JtYWxpc2UgYnkgcmF3IHJlYWQgY291bnQKCnJlYWRfY291bnRfbm9ybTEgPC0gY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKG5vcm1fY291bnRzMSksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHlsYWIoIkxvZyh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpCgojbm9ybWFsaXNlIGJ5IHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoCgpyZWFkX2NvdW50X25vcm0yIDwtIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZyhub3JtX2NvdW50czIpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV94X2xvZzEwKCkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICB5bGFiKCJMb2codmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcy9nZW5vbWUgbGVuZ3RoKSIpCgoKYGBgCgojIyMgcGxvdCBqdXN0IHRoZSB0d28gbGVmdGhhbmQgcGFuZWxzIGZyb20gdGhlIG9yaWdpbmFsIGZpZ3VyZQpgYGB7ciwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTh9CgpnZ2FycmFuZ2UocmVhZF9jb3VudCwKICAgICAgICAgIHJlYWRfY291bnRfbm9ybTIsCiAgICAgICAgICBucm93ID0gMiwKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBUUlVFKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL2xvZ19yZWFkX2NvdW50X2RlcHRoXzJwYW5lbHMucG5nIix3aWR0aD0xMCxoZWlnaHQ9NykKCgpgYGAKCiMjIyBwbG90IHZpcmFsIHJlYWQgY291bnRzIChub24gbm9ybWFsaXNlZCkKYGBge3J9CgojI2RlZHVwbGljYXRlZCBvbmx5CgpyZWFkX2NvdW50X2RlZHVwIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKG1hdGNoZWQpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHlsYWIoIkxvZyhWaXJhbCBSZWFkcykiKSArCiAgeGxhYigiVmlyYWwgbG9hZCIpCgojbm9ybWFsaXNlIGJ5IHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoCgpyZWFkX2NvdW50X25vcm0yX2RlZHVwIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKG5vcm1fY291bnRzMiksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeF9sb2cxMCgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgeWxhYigiTG9nKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArCiAgeGxhYigiVmlyYWwgbG9hZCIpCgpgYGAKCiMjIyAqKipGaW5hbCBwbG90KioqCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTYsIGZpZy5oZWlnaHQ9OH0KI3Bsb3QganVzdCB0aGUgdHdvIGxlZnRoYW5kIHBhbmVscyBmcm9tIHRoZSBvcmlnaW5hbCBmaWd1cmUKCmdnYXJyYW5nZSgKICByZWFkX2NvdW50X2RlZHVwLAogIHJlYWRfY291bnRfbm9ybTJfZGVkdXAsCiAgbnJvdyA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCiMgZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvbG9nX3JlYWRfY291bnRfZGVwdGhfMnBhbmVsc19kZWR1cC5wbmciLAojICAgICAgICB3aWR0aD0xMCwKIyAgICAgICAgaGVpZ2h0PTcpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlXzEucGRmIiwKICAgICAgIHdpZHRoPTYsCiAgICAgICBoZWlnaHQ9OCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfMS5wbmciLAogICAgICAgd2lkdGg9NiwKICAgICAgIGhlaWdodD04KQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWd1cmUgUzEKCiMjIyBSZWFkIGRlcHRocwpgYGB7cn0KIyMjI3JlYWQgZGVwdGhzIyMjIwoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpkZXB0aF9ub2RlZHVwX2J0IDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKZGVwdGhzX2J0X2FsbCA8LSByYmluZChkZXB0aF9kZWR1cF9idCwgZGVwdGhfbm9kZWR1cF9idCkKCmRlcHRoc19yZWFkcyA8LSAKICBkZXB0aHNfYnRfYWxsIHw+CiAgbGVmdF9qb2luKG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkKCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3J9CgpyZWFkX2RlcHRocyA8LSAKICBkZXB0aHNfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfeF9sb2cxMCgpICsKICB5bGFiKCJMb2cobWVhbiByZWFkIGRlcHRoKSIpCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvbWVhbl9kZXB0aC5wZGYiLHdpZHRoPTgsaGVpZ2h0PTYpCgpgYGAKCiMjIyAqKipGaW5hbCBwbG90KioqCmBgYHtyfQoKZ2dhcnJhbmdlKAogIHJlYWRfY291bnQsCiAgcmVhZF9jb3VudF9ub3JtMSwKICByZWFkX2NvdW50X25vcm0yLAogIHJlYWRfZGVwdGhzLAogIG5yb3cgPSAyLAogIG5jb2wgPSAyLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvbG9nX3JlYWRfY291bnRfZGVwdGgucG5nIix3aWR0aD0xMCxoZWlnaHQ9NykKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTMS5wZGYiLHdpZHRoPTEwLGhlaWdodD03KQoKI2FwcGFyZW50bHkgbm9ybWFsaXNlZCByZWFkIGNvdW50IHVzaW5nIG1ldGhvZCAyIHNob3VsZCBub3QgYWN0dWFsbHkgYmUgdGhlIHNhbWUKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlndXJlIFMyCgojIyMgUmVhZWQtaW4gZGF0YSAvIE1ha2UgcGxvdHMKYGBge3J9CiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigKICAgICJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKbWV0YWRhdGEyIDwtIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgY291bnQgZmlsZXMKI2RlZHVwbGljYXRlZCBhbmQgbm9uLWRlZHVwbGljYXRlZAoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfYnRfYWxsIDwtIHJiaW5kKGNvdW50c19kZWR1cF9idCwgY291bnRzX25vZGVkdXBfYnQpCgpjb3VudHNfcmVhZHMgPC0gbGVmdF9qb2luKGNvdW50c19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCiNub3JtYWxpc2UgYnkgYm90aCByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aCAtIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBtZWFuIHJlYWQgZGVwdGgKCmNvdW50c19yZWFkc19ub3JtIDwtIGNvdW50c19yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdW50czEgPSBtYXRjaGVkIC8gUUNfcmVhZHMpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMiA9IG1hdGNoZWQgLyBRQ19yZWFkcyAvIGxlbmd0aCkgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCiMjIyNjb21wYXJlIGxpYnJhcnkgY2FwdHVyZSBwb29sIyMjIwoKY29sczMgPC0gYygiIzIyODgzMyIsICIjQUEzMzc3IikKCmZhY2V0X25hbWVzIDwtIGMoImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIikKCm1ldGFkYXRhMyA8LSAKICBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIFBvb2wuZm9yLnNlcXVlbmNpbmcpIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUG9vbCA9IFBvb2wuZm9yLnNlcXVlbmNpbmcpCgpjb3VudHNfcG9vbCA8LSBsZWZ0X2pvaW4oY291bnRzX3JlYWRzX25vcm0sIG1ldGFkYXRhMywgYnkgPSAiU2FtcGxlX2lkIikKCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3J9Cgpwb29sX3JlYWRjb3VudHMgPC0gCiAgY291bnRzX3Bvb2wgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IGxvZyhtYXRjaGVkKSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZChQb29sIH4gdHlwZSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKFZpcmFsIFJlYWRzKSIpICsgeGxhYigiVmlyYWwgbG9hZCAoY29waWVzIC8gbWwpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKQoKcG9vbF9jb3VudHNfc3VtIDwtIAogIGNvdW50c19wb29sIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCksCiAgICB5ID0gbG9nKG1hdGNoZWQpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKFZpcmFsIFJlYWRzKSIpICsgeGxhYigiVmlyYWwgbG9hZCAoY29waWVzIC8gbWwpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKQoKcG9vbF9yZWFkY291bnRzX25vcm0gPC0gCiAgY291bnRzX3Bvb2wgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IGxvZyhub3JtX2NvdW50czEpKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF9ncmlkKFBvb2wgfiB0eXBlKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgIyBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHlsYWIoIkxvZyh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpICsgIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpCgpwb29sX25vcm0xX3N1bSA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZyhtYXRjaGVkKSwKICAgIGNvbG91ciA9IFBvb2wKICApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICAjIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgeWxhYigiTG9nKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMpIikgKyAgIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczMsIGxhYmVscyA9IGMoIlBvb2wgMSIsICJQb29sIDIiKSkKCnBvb2xfcmVhZGNvdW50c19ub3JtMiA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoeCA9IHZpcnVzLCB5ID0gbG9nKG5vcm1fY291bnRzMikpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X2dyaWQoUG9vbCB+IHR5cGUpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICAjIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgeWxhYigiTG9nKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpCgoKcG9vbF9ub3JtMl9zdW0gPC0gCiAgY291bnRzX3Bvb2wgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKSwKICAgIHkgPSBsb2cobWF0Y2hlZCksCiAgICBjb2xvdXIgPSBQb29sCiAgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgIyBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHlsYWIoIkxvZyh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzL2dlbm9tZSBsZW5ndGgpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKSArIAogIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpCgoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZGVwdGhfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aHNfYnRfYWxsIDwtIHJiaW5kKGRlcHRoX2RlZHVwX2J0LCBkZXB0aF9ub2RlZHVwX2J0KQoKZGVwdGhzX3JlYWRzIDwtIAogIGxlZnRfam9pbihkZXB0aHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKAogICAgdmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiIHwKICAgICAgdmlydXMgPT0gIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIKICApIH4gIkROQSIsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpkZXB0aHNfcG9vbCA8LSBsZWZ0X2pvaW4oZGVwdGhzX3JlYWRzLCBtZXRhZGF0YTMsIGJ5ID0gIlNhbXBsZV9pZCIpCgpwb29sX3JlYWRkZXB0aHMgPC0gCiAgZGVwdGhzX3Bvb2wgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IGxvZyhtZWFuX2RlcHRoKSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZChQb29sIH4gdHlwZSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgeWxhYigiTG9nIChtZWFuIHJlYWQgZGVwdGgpIikgKyB4bGFiKCJWaXJhbCBsb2FkIChjb3BpZXMgLyBtbCkiKQoKcG9vbF9kZXB0aHNfc3VtIDwtIAogIGRlcHRoc19wb29sIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCksCiAgICB5ID0gbG9nKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKG1lYW4gcmVhZCBkZXB0aCkiKSArCiAgeGxhYigiVmlyYWwgbG9hZCAoY29waWVzIC8gbWwpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKQoKYGBgCgojIyMgRmluYWwgcGxvdApgYGB7cn0KZ2dhcnJhbmdlKAogIHBvb2xfY291bnRzX3N1bSwKICBwb29sX25vcm0xX3N1bSwKICBwb29sX25vcm0yX3N1bSwKICBwb29sX2RlcHRoc19zdW0sCiAgbnJvdyA9IDIsCiAgbmNvbCA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9wb29sX2NvbXBhcmVfdmlydXNlc19zdW0ucG5nIix3aWR0aD0xMCxoZWlnaHQ9NykKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTMi5wZGYiLHdpZHRoPTEwLGhlaWdodD03KQoKYGBgCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEZpZ3VyZSBTMwpgYGB7cn0KCiMjcGxvdHMgb2YgcmVhZCBjb3VudHMgYW5kIHZpcmFsIHJlYWQgY291bnRzCiNOb3ZlbWJlciAyMDI0CgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtCiAgcmVhZC5jc3YoCiAgICAibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCm1ldGFkYXRhMiA8LSBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCByZWFkIGNvdW50IGZpbGVzCgpjb3VudHNfZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCiNpbXBvcnQgdmlyYWwgcmVhZHMgbWFwcGVkICh0byBjYWxjdWxhdGUgcHJvcG9ydGlvbnMpCgp2aXJhbF9yZWFkc19kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvdG90YWxfdmlydXNfbWFwcGVkX3JlYWRzX3Blcl9zYW1wbGVfZGVkdXBfYXRjY19yZWZfMjAyNDExMDguY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgp2aXJhbF9yZWFkc19ub2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS90b3RhbF92aXJ1c19tYXBwZWRfcmVhZHNfcGVyX3NhbXBsZV9ub2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA4LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY29sczIgPC0gYygiI0JCNTU2NiIsICIjMDA0NDg4IikKCmZhY2V0X25hbWVzIDwtIGMoImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIikKCnJlYWRzX21ldGFkYXRhX2RlZHVwIDwtCiAgbGVmdF9qb2luKGNvdW50c19kZWR1cF9idCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKcmVhZHNfdmlyYWxfZGVkdXAgPC0KICBsZWZ0X2pvaW4ocmVhZHNfbWV0YWRhdGFfZGVkdXAsIHZpcmFsX3JlYWRzX2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKQoKcmVhZHNfbWV0YWRhdGFfbm9kZWR1cCA8LQogIGxlZnRfam9pbihjb3VudHNfbm9kZWR1cF9idCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKcmVhZHNfdmlyYWxfbm9kZWR1cCA8LQogIGxlZnRfam9pbihyZWFkc19tZXRhZGF0YV9ub2RlZHVwLCB2aXJhbF9yZWFkc19ub2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKQoKcmVhZHNfdmlyYWxfYWxsIDwtIHJiaW5kKHJlYWRzX3ZpcmFsX2RlZHVwLCByZWFkc192aXJhbF9ub2RlZHVwKQoKCnJlYWRzX3Bsb3QgPC0gCiAgcmVhZHNfdmlyYWxfYWxsIHw+CiAgZ3JvdXBfYnkoQmFja2dyb3VuZCwgU2FtcGxlX2lkLCBWaXJhbC5sb2FkLCB0eXBlKSB8PgogIHN1bW1hcmlzZSgKICAgIHRvdGFsX3JlYWRzID0gKFFDX3JlYWRzICogMiksCiAgICB2aXJhbF9yZWFkcyA9IHRvdGFsX3ZpcnVzX3JlYWRzLAogICAgQVRDQ19yZWFkcyA9IHN1bShtYXRjaGVkKSwKICAgIHByb3BfQVRDQyA9IEFUQ0NfcmVhZHMgLyB0b3RhbF9yZWFkcywKICAgIHByb3BfdmlyYWwgPSB0b3RhbF92aXJ1c19yZWFkcyAvIHRvdGFsX3JlYWRzLAogICAgZGlmZiA9IHZpcmFsX3JlYWRzIC0gQVRDQ19yZWFkcwogICkgfD4KICB1bmlxdWUoKQoKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCnRvdGFsX3JlYWRzIDwtIAogIHJlYWRzX3Bsb3QgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKHRvdGFsX3JlYWRzKSwKICAgIGNvbG91ciA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX2xvZygpKSArIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpICsKICBnZ3RpdGxlKCJUb3RhbCBSZWFkcyIpICsKICB5bGFiKCJMb2coVG90YWwgUmVhZHMpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCnZpcmFsX3JlYWRzIDwtIAogIHJlYWRzX3Bsb3QgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKHZpcmFsX3JlYWRzKSwKICAgIGNvbG91ciA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX2xvZygpKSArIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpICsKICBnZ3RpdGxlKCJUb3RhbCBWaXJhbCBSZWFkcyIpICsKICB5bGFiKCJMb2coVG90YWwgVmlyYWwgUmVhZHMpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCkFUQ0NfcmVhZHMgPC0gCiAgcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2coQVRDQ19yZWFkcyksCiAgICBjb2xvdXIgPSBCYWNrZ3JvdW5kCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gQmFja2dyb3VuZCksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2coKSkgKyB4bGFiKCJWaXJhbCBsb2FkIChjb3BpZXMgLyBtbCkiKSArCiAgZ2d0aXRsZSgiU3Bpa2UgSW4gVmlyYWwgUmVhZHMiKSArCiAgeWxhYigiTG9nKFNwaWtlIEluIFZpcmFsIFJlYWRzKSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIlAxIiwgIlAyIikpCgpwcm9wX0FUQ0MgPC0gcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX0FUQ0MsIGNvbG91ciA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX2xvZygpKSArIHhsYWIoIlZpcmFsIGxvYWQgKGNvcGllcyAvIG1sKSIpICsKICBnZ3RpdGxlKCJQcm9wb3J0aW9uIFNwaWtlIEluIFZpcmFsIikgKwogIHlsYWIoIlNwaWtlIEluIFZpcmFsIFJlYWRzL1RvdGFsIFJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCnByb3BfdmlyYWwgPC0gcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX3ZpcmFsLCBjb2xvdXIgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gQmFja2dyb3VuZCksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2coKSkgKyB4bGFiKCJWaXJhbCBsb2FkIChjb3BpZXMgLyBtbCkiKSArCiAgZ2d0aXRsZSgiUHJvcG9ydGlvbiBWaXJhbCIpICsKICB5bGFiKCJWaXJhbCBSZWFkcy9Ub3RhbCBSZWFkcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIlAxIiwgIlAyIikpCgoKI2dnYXJyYW5nZSh0b3RhbF9yZWFkcyx2aXJhbF9yZWFkcyxBVENDX3JlYWRzLHByb3BfdmlyYWwscHJvcF9BVENDLG5yb3c9MixuY29sPTMsY29tbW9uLmxlZ2VuZCA9IFRSVUUpCgpgYGAKCiMjIyAqKipGaW5hbCBwbG90KioqCmBgYHtyfQpnZ2FycmFuZ2UodG90YWxfcmVhZHMsCiAgICAgICAgICB2aXJhbF9yZWFkcywKICAgICAgICAgIHByb3BfdmlyYWwsCiAgICAgICAgICBucm93ID0gMywKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogICAgICAgICAgYWxpZ24gPSAiaHYiKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL2JhY2tncm91bmRzX3JlYWRzLnBuZyIpCgojZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlc19wZGYvRmlndXJlUzMucGRmIikKCiMjIyNjb21wYXJlIHByb3BvcnRpb24gdmlyYWwgcmVhZHMgcGVyIHBvb2wgd2l0aCBzaG90Z3VuIyMjIwoKIyBtZXRhZGF0YTMgPC0gbWV0YWRhdGEgfD4KIyAgIHNlbGVjdChTYW1wbGUuSUQsCiMgICAgICAgICAgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLiwKIyAgICAgICAgICBQb29sLmZvci5zZXF1ZW5jaW5nKSB8PgojICAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KIyAgIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCiMgCiMgcmVhZHNfdmlyYWxfZGVkdXAzIDwtCiMgICBmdWxsX2pvaW4obWV0YWRhdGEzLCB2aXJhbF9yZWFkc19kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikKIyAKIyByZWFkc192aXJhbF9ub2RlZHVwMyA8LQojICAgZnVsbF9qb2luKG1ldGFkYXRhMywgdmlyYWxfcmVhZHNfbm9kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikKIyAKIyByZWFkc192aXJhbF9kZWR1cDMgfD4KIyAgIGdyb3VwX2J5KFBvb2wuZm9yLnNlcXVlbmNpbmcpIHw+CiMgICBzdW1tYXJpc2UoCiMgICAgIHZpcmFsX3JlYWRzID0gc3VtKHRvdGFsX3ZpcnVzX3JlYWRzKSwKIyAgICAgdG90YWxfcmVhZHMgPSBzdW0oUUNfcmVhZHMgKiAyKSwKIyAgICAgcHJvcF92aXJhbCA9IHZpcmFsX3JlYWRzIC8gdG90YWxfcmVhZHMKIyAgICkKIyAKIyBwb2x5b21pY3MgPC0KIyAgIHJlYWQuY3N2KAojICAgICAiZGF0YV9wb2x5b21pY3MvdG90YWxfdmlydXNfbWFwcGVkX3JlYWRzX3Blcl9zYW1wbGVfZGVkdXAuY3N2IgojICAgKQojIAojICNyZWFkIGRhdGEgZnJvbSBwb2x5b21pY3NfaW5kZXhlc19zdGVmYW5vIGRvY3VtZW50CiMgdG90YWxfcmVhZHMgPC0gZGF0YS5mcmFtZSh0b3RhbF9yZWFkcyA9IGMoNTk0Mjc2MCwgNzcxNDI3NSkpCiMgCiMga2VlcHMgPC0gYygiUk5BLU1zcC1wMiIsICJSTkEtTXNwLXA4IikKIyAKIyBwb2x5b21pY3NfcmVhZF9wcm9wIDwtIHBvbHlvbWljcyB8PgojICAgZmlsdGVyKFNhbXBsZV9pZCAlaW4lIGtlZXBzKQojIAojIHBvbHlvbWljc19yZWFkX3Byb3AyIDwtIGNiaW5kKHBvbHlvbWljc19yZWFkX3Byb3AsIHRvdGFsX3JlYWRzKQojIAojIHBvbHlvbWljc19yZWFkX3Byb3AyIHw+CiMgICBzdW1tYXJpc2UocHJvcF92aXJhbCA9IHRvdGFsX3ZpcnVzX3JlYWRzIC8gdG90YWxfcmVhZHMpCgpgYGAKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlndXJlIFM0CgojIyMgTWFrZSBwbG90cwpgYGB7cn0KIyMjI3JlYWQgY291bnRzL2RlcHRocyBzcGxpdCBieSBiYWNrZ3JvdW5kIyMjIwoKI2NoYW5nZSBsYWJlbHMgaW4gZmFjZXQgcGxvdHMKCmZhY2V0X25hbWVzX2JnIDwtIGMoCiAgImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIiwKICAicDIiID0gIlAxIiwKICAicDgiID0gIlAyIgopCgojYnJlYWsgZG93biBieSBCYWNrZ3JvdW5kIHggdmlydXMKCmJhY2tncm91bmRfY291bnRzX3JlYWRzIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZyhtYXRjaGVkKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzX2JnKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0KICAgICAgYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICAgICkKICApICsKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbG9nKCkpICsKICB5bGFiKCJMb2coVmlyYWwgUmVhZHMpIikKCmJhY2tncm91bmRzX2NvdW50c19yZWFkc19ub3JtIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZyhub3JtX2NvdW50czEpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXNfYmcpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV94X2xvZzEwKGxhYmVsID0gc2NhbGVzOjpsYWJlbF9sb2coKSkgKwogIHlsYWIoIkxvZyh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpCgpiYWNrZ3JvdW5kc19jb3VudHNfcmVhZHNfbm9ybTIgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nKG5vcm1fY291bnRzMiksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZChCYWNrZ3JvdW5kIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lc19iZykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2coKSkgKwogIHlsYWIoIkxvZyh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzL2dlbm9tZSBsZW5ndGgpIikKCmJhY2tncm91bmRfcmVhZF9kZXB0aHMgPC0gCiAgZGVwdGhzX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZyhtZWFuX2RlcHRoKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzX2JnKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbCA9IHNjYWxlczo6bGFiZWxfbG9nKCkpICsKICB5bGFiKCJMb2cobWVhbiByZWFkIGRlcHRoKSIpCgpgYGAKCiMjIyAqKipGaW5hbCBwbG90KioqIApgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD02LCBmaWcuaGVpZ2h0PTh9CgpnZ2FycmFuZ2UoCiAgYmFja2dyb3VuZF9jb3VudHNfcmVhZHMsCiAgYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0sCiAgYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0yLAogIGJhY2tncm91bmRfcmVhZF9kZXB0aHMsCiAgbnJvdyA9IDIsCiAgbmNvbCA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9iYWNrZ3JvdW5kc19yZWFkX2NvdW50X2RlcHRoLnBuZyIsd2lkdGg9MTAsaGVpZ2h0PTcpCgojZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlc19wZGYvRmlndXJlUzQucGRmIix3aWR0aD0xMCxoZWlnaHQ9NykKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTNSAtIGxpbmVhciBtb2RlbAoKIyMjIyBSZWFkLWluIGRhdGEKYGBge3J9CiNMaW5lYXIgbW9kZWwgZm9yIFRFIGRhdGEgLSBzZXBhcmF0ZWQgYnkgdmlydXMKI05vdmVtYmVyIDIwMjQKCiN2aXJhbCByZWFkIGRlcHRoCiN1c2UgYm93dGllMiBkYXRhCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShib290KQoKIyMjI3JlYWQgY291bnRzL25vcm1hbGlzZWQgcmVhZCBjb3VudHMjIyMjCgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtCiAgcmVhZC5jc3YoCiAgICAibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCm1ldGFkYXRhMiA8LSBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGNvdW50IGZpbGVzCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX25vZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX2J0X2FsbCA8LSByYmluZChjb3VudHNfZGVkdXBfYnQsIGNvdW50c19ub2RlZHVwX2J0KQoKY291bnRzX3JlYWRzIDwtIGxlZnRfam9pbihjb3VudHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIyMjcmVhZCBkZXB0aHMjIyMjCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgZGVwdGggZmlsZXMKCmRlcHRoX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aF9ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmBgYAoKIyMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KCmRlcHRoc19idF9hbGwgPC0gcmJpbmQoZGVwdGhfZGVkdXBfYnQsIGRlcHRoX25vZGVkdXBfYnQpCgpkZXB0aHNfcmVhZHMgPC0gbGVmdF9qb2luKGRlcHRoc19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgojIyMjbGluZWFyIG1vZGVsIGZvciBzcGlrZSBpbiB2aXJ1c2VzIC0gbWVhbiByZWFkIGRlcHRoIyMjIwoKZGVwdGhzX3JlYWRzX3N1YiA8LSBkZXB0aHNfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIG11dGF0ZShsb2dfZGVwdGggPSBsb2cobWVhbl9kZXB0aCkpIHw+CiAgbXV0YXRlKGxvZ192aXJhbF9sb2FkID0gbG9nMTAoVmlyYWwubG9hZCkpCgojaW5zcGVjdCBkYXRhCmhpc3QoZGVwdGhzX3JlYWRzX3N1YiRtZWFuX2RlcHRoKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkVmlyYWwubG9hZCkKaGlzdChkZXB0aHNfcmVhZHNfc3ViJGxvZ19kZXB0aCkKaGlzdChkZXB0aHNfcmVhZHNfc3ViJGxvZ192aXJhbF9sb2FkKQoKc3VtbWFyeShkZXB0aHNfcmVhZHNfc3ViJGxvZ19kZXB0aCkKc3VtbWFyeShkZXB0aHNfcmVhZHNfc3ViJGxvZ192aXJhbF9sb2FkKQoKYGBgCgojIyMjIG1vZGVsCmBgYHtyfQojYWxsIHZpcnVzZXMgdG9nZXRoZXIKCmxtMSA8LQogIGdsbShsb2dfZGVwdGggfiBsb2dfdmlyYWxfbG9hZCAqIHZpcnVzLAogICAgICBkYXRhID0gZGVwdGhzX3JlYWRzX3N1YiwKICAgICAgZmFtaWx5ID0gImdhdXNzaWFuIikKCnN1bW1hcnkobG0xKQoKZ2xtLmRpYWcucGxvdHMobG0xKQoKcHJlZCA8LSBwcmVkaWN0KGxtMSwgdHlwZSA9ICJyZXNwb25zZSIpCgpyc3EgPC0gZnVuY3Rpb24gKHgsIHkpIHsKICBjb3IoeCwgeSkgXiAyCn0KCnJzcShkZXB0aHNfcmVhZHNfc3ViJGxvZ19kZXB0aCwgcHJlZCkKCiMjc3BsaXQgYnkgdmlydXNlcwoKY29scyA8LSBjKCIjNDQ3N0FBIiwKICAgICAgICAgICIjNjZDQ0VFIiwKICAgICAgICAgICIjMjI4ODMzIiwKICAgICAgICAgICIjQ0NCQjQ0IiwKICAgICAgICAgICIjRUU2Njc3IiwKICAgICAgICAgICIjQUEzMzc3IikKCmZhY2V0X25hbWVzIDwtIGMoCiAgIkh1bWFuX2FkZW5vdmlydXNfNDAiID0gIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICJIdW1hbl9iZXRhaGVycGVzdmlydXMiID0gIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgIkh1bWFuX3Jlc3BpcmF0b3J5X3N5bmN5dGlhbF92aXJ1cyIgPSAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAiSW5mbHVlbnphX0JfdmlydXMiID0gIkluZmx1ZW56YSBCIHZpcnVzIiwKICAiTWFtbWFsaWFuX29ydGhvcmVvdmlydXMzIiA9ICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAiWmlrYV92aXJ1cyIgPSAiWmlrYSB2aXJ1cyIKKQoKdmlydXMgPC0gKHVuaXF1ZShkZXB0aHNfcmVhZHNfc3ViJHZpcnVzKSkgfD4KICByZXAoZWFjaCA9IDIpIHw+CiAgZGF0YS5mcmFtZSgpIHw+CiAgcmVuYW1lKHZpcnVzID0gcmVwLi51bmlxdWUuZGVwdGhzX3JlYWRzX3N1Yi52aXJ1cy4uLi5lYWNoLi4uMi4pCgpsaXN0X21vZGVscyA8LSAKICBkZXB0aHNfcmVhZHNfc3ViIHw+CiAgZ3JvdXBfc3BsaXQodmlydXMpIHw+CiAgbWFwKCB+IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkLCBkYXRhID0gLikpCgpsbV90aWR5IDwtIAogIG1hcChsaXN0X21vZGVscywgYnJvb206OnRpZHkpIHw+CiAgZG8uY2FsbChyYmluZC5kYXRhLmZyYW1lLCAuKSB8PgogIGNiaW5kKHZpcnVzLCAuKSB8PgogIHJlbmFtZSh2aXJ1cyA9ICIuIikgfD4KICBzZWxlY3QodmlydXMsIHRlcm0sIGVzdGltYXRlKSB8PgogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAidGVybSIsIHZhbHVlc19mcm9tID0gImVzdGltYXRlIikKCmxtX3N1bW1hcnkgPC0gZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX2J5KHZpcnVzKSB8PgogIHN1bW1hcmlzZSgKICAgIEludGVyY2VwdCA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMV0sCiAgICBDb2VmZl94MSA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMl0sCiAgICBSMiA9IHN1bW1hcnkobG0obG9nX2RlcHRoIH4gbG9nX3ZpcmFsX2xvYWQpKSRyLnNxdWFyZWQsCiAgICBwdmFsdWUgPSBzdW1tYXJ5KGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSkkY29lZmZpY2llbnRzWyJsb2dfdmlyYWxfbG9hZCIsIDRdCiAgKQoKbG1fY29tYmluZWQgPC0gbGVmdF9qb2luKGxtX3RpZHksIGxtX3N1bW1hcnksIGJ5ID0gInZpcnVzIikKCmdncGxvdCgpICsKICBnZW9tX3BvaW50KGRhdGEgPSBkZXB0aHNfcmVhZHNfc3ViLAogICAgICAgICAgICAgbWFwcGluZyA9IGFlcyhsb2dfdmlyYWxfbG9hZCwgbG9nX2RlcHRoLCBjb2xvciA9IHZpcnVzKSkgKwogIGdlb21fYWJsaW5lKGRhdGEgPSBsbV9jb21iaW5lZCwgYWVzKGludGVyY2VwdCA9IGAoSW50ZXJjZXB0KWAsIHNsb3BlID0gbG9nX3ZpcmFsX2xvYWQpKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBsbV9jb21iaW5lZCwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKAogICAgICAgICAgICAgIHggPSA0LjcsCiAgICAgICAgICAgICAgeSA9IDMsCiAgICAgICAgICAgICAgbGFiZWwgPSByb3VuZChDb2VmZl94MSwgZGlnaXRzID0gMikKICAgICAgICAgICAgKSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcyh4ID0gNCwgeSA9IDMsIGxhYmVsID0gIlNsb3BlID0iKSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICB4ID0gNC43LAogICAgICAgICAgICAgIHkgPSAyLAogICAgICAgICAgICAgIGxhYmVsID0gcm91bmQoUjIsIGRpZ2l0cyA9IDIpCiAgICAgICAgICAgICkpICsKICBnZW9tX3RleHQoZGF0YSA9IGxtX2NvbWJpbmVkLAogICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLAogICAgICAgICAgICBhZXMoeCA9IDQsIHkgPSAyLCBsYWJlbCA9ICJSMiA9IikpICsKICBmYWNldF93cmFwKCB+IHZpcnVzLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2J3KCkgKwogIHhsYWIoIkxvZyhWaXJhbCBMb2FkKSIpICsKICB5bGFiKCJMb2coTWVhbiBSZWFkIERlcHRoKSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogIGd1aWRlcyhjb2xvciA9IEZBTFNFKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL21vZGVsX3JlYWRkZXB0aF9kZWR1cC5wbmciKQoKI2dnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZXNfcGRmL0ZpZ3VyZVM1LnBkZiIpCgpgYGAKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgPj4+IEZpZ3VyZSAyOiBwbG90cyBvZiBURSBleHBlcmltZW50IGRhdGEgLSBnZW5vbWUgY292ZXJhZ2UgJiBwZXIgc2l0ZSBjb3ZlcmFnZQoKIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KCiNwbG90cyBvZiBURSBleHBlcmltZW50IGRhdGEgLSBnZW5vbWUgY292ZXJhZ2UgJiBwZXIgc2l0ZSBjb3ZlcmFnZQojYWxzbyBzZXBhcmF0ZWQgYnkgdmlydXNlcwojQVRDQyBnZW5vbWVzIHVwZGF0ZWQgdmVyc2lvbgojT2N0b2JlciAyMDI0CgojdXNlIGJvd3RpZTIgZGF0YQoKIyMjI2dlbm9tZSBjb3ZlcmFnZSMjIyMKCnVuemlwKHppcGZpbGUgPSAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YuemlwIiwgZXhkaXIgPSAiZGF0YV9URS8iKQoKdW56aXAoemlwZmlsZSA9ICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2LnppcCIsIGV4ZGlyID0gImRhdGFfVEUvIikKCmRlZHVwX3Blcl9zaXRlIDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKCm5vZGVkdXBfcGVyX3NpdGUgPC0KICByZWFkX3RzdigKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmZpbGUucmVtb3ZlKCJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIpCgpmaWxlLnJlbW92ZSggImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiKQoKI2FkZCBsZW5ndGggY29sdW1uIGZyb20gcmVhZCBkZXB0aCBmaWxlIHRvIHBlciBzaXRlIGZpbGUKCiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigKICAgICJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKbWV0YWRhdGEyIDwtIAogIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgY291bnQgZmlsZXMKCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKYGBgCgojIyMgRm9ybWF0IGRhdGEKYGBge3J9CiNub3JtYWxpc2UgYnkgYm90aCByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aCAtIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBtZWFuIHJlYWQgZGVwdGgKCmNvdW50c19yZWFkc19ub3JtIDwtIAogIGNvdW50c19yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdW50czEgPSBtYXRjaGVkIC8gUUNfcmVhZHMpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMiA9IG1hdGNoZWQgLyBRQ19yZWFkcyAvIGxlbmd0aCkgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCmxlbmd0aHMgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBzZWxlY3QodmlydXMsIGxlbmd0aCkgfD4KICBkaXN0aW5jdCgpCgojY2FsY3VsYXRlIGdlbm9tZSBjb3ZlcmFnZQoKcGVyc2l0ZV9jb3ZlcmFnZV9kZWR1cCA8LSAKICBkZWR1cF9wZXJfc2l0ZSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdyb3VwX2J5KFNhbXBsZV9pZCwgdmlydXMsIFZpcmFsLmxvYWQsIEJhY2tncm91bmQsIHR5cGUpIHw+CiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgfD4KICBzdW1tYXJpc2UoZ2Vub21lX2NvdmVyYWdlID0gbigpKSB8PgogIGxlZnRfam9pbihsZW5ndGhzKSB8PgogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gbGVuZ3RoKQoKcGVyc2l0ZV9jb3ZlcmFnZV9ub2RlZHVwIDwtIAogIG5vZGVkdXBfcGVyX3NpdGUgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBncm91cF9ieShTYW1wbGVfaWQsIHZpcnVzLCBWaXJhbC5sb2FkLCBCYWNrZ3JvdW5kLCB0eXBlKSB8PgogIGZpbHRlcihjb3ZlcmFnZSA+IDApIHw+CiAgc3VtbWFyaXNlKGdlbm9tZV9jb3ZlcmFnZSA9IG4oKSkgfD4KICBsZWZ0X2pvaW4obGVuZ3RocykgfD4KICBtdXRhdGUocGVyY2VudF9jb3ZlcmFnZSA9IGdlbm9tZV9jb3ZlcmFnZSAvIGxlbmd0aCkKCnBlcnNpdGVfY292ZXJhZ2VfYm90aCA8LQogIHJiaW5kKHBlcnNpdGVfY292ZXJhZ2VfZGVkdXAsIAogICAgICAgIHBlcnNpdGVfY292ZXJhZ2Vfbm9kZWR1cCkKCmNvdmVyYWdlX2xhYmVscyA8LSBjKCIwIiA9ICJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgIjEwMCIgPSAiMTBeezJ9IiwKICAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgICIxMDAwMCIgPSAiMTBeezV9IiwKICAgICAgICAgICAgICAgICAgICAgImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICAgICAibm9kZWR1cF9URSI9ICJOb24tRGVkdXBsaWNhdGVkIikKCmNvdmVyYWdlX2xhYmVsczIgPC0gYygiMCIgPSAiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwIiA9ICIxMF57Mn0iLAogICAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwMDAiID0gIjEwXns1fSIpCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KCmNvbHMyIDwtIGMoIiNCQjU1NjYiLAogICAgICAgICAgICIjMDA0NDg4IikKCmNvbHM0IDwtIGMoIiNEREFBMzMiLAogICAgICAgICAgICIjQkI1NTY2IiwKICAgICAgICAgICAiIzAwNDQ4OCIpCgoKcGVyc2l0ZV9jb3ZlcmFnZV9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKHBlcnNpdGVfY292ZXJhZ2VfYm90aCRWaXJhbC5sb2FkLCBsYWJlbHMgPSBjKCIwIiwKICAgICIxMF57Mn0iLCAKICAgICIxMF57M30iLCAKICAgICIxMF57NX0iCiAgICApKQoKCiMjYXJlIHRoZSBkZWR1cGxpY2F0ZWQgYW5kIG5vbiBkZWR1cGxpY2F0ZWQgZGF0YXNldHMgaWRlbnRpY2FsPz8KIyNpZiB0aGV5IGFyZSB0aGUgc2FtZSBjYW4gbWF5YmUganVzdCBzaG93IG9uZQojc2hvdyBkZWR1cGxpY2F0ZWQKCnBlcnNpdGVfY292ZXJhZ2VfYm90aCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBwZXJjZW50X2NvdmVyYWdlLCBjb2xvdXIgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuNzUpKSArCiAgZmFjZXRfZ3JpZCh+YXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLCBsYWJlbGxlciA9IGxhYmVsX3BhcnNlZCkgKwogIHRoZW1lX2ZldygpICsKICB5bGFiKCJHZW5vbWUgY292ZXJhZ2UiKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJQMSIsICJQMiIpKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEpKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7ciwgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvZ2Vub21lX2Nvdl9kZWR1cG9ubHkucG5nIix3aWR0aD0xNSxoZWlnaHQ9NikKCmdnc2F2ZSgKICAiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfMi5wZGYiLAogIHdpZHRoID0gMTUsCiAgaGVpZ2h0ID0gNgopCgpnZ3NhdmUoCiAgImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlXzIucG5nIiwKICB3aWR0aCA9IDE1LAogIGhlaWdodCA9IDYKKQoKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTNgpgYGB7cn0KCnBlcnNpdGVfYm90aCA8LSByYmluZChkZWR1cF9wZXJfc2l0ZSwgbm9kZWR1cF9wZXJfc2l0ZSkKCnBlcnNpdGVfcmVhZHMgPC0gbGVmdF9qb2luKHBlcnNpdGVfYm90aCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKcGVyc2l0ZV9ub3JtIDwtIHBlcnNpdGVfcmVhZHMgfD4KICBtdXRhdGUobm9ybV9jb3YgPSBjb3ZlcmFnZSAvIFFDX3JlYWRzKQoKY292ZXJhZ2VfbGFiZWxzMyA8LWMoIjEwMCIgPSAiMWUrMDIiLAogICAgICAgICAgICAgICAgICAgICIxMDAwIiA9ICIxZSswMyIsCiAgICAgICAgICAgICAgICAgICAgIjEwMDAwMCIgPSAiMWUrMDUiLAogICAgICAgICAgICAgICAgICAgICJwMiIgPSAiUDEiLAogICAgICAgICAgICAgICAgICAgICJwOCI9ICJQMiIpCgpwZXJzaXRlX25vcm0kYFZpcmFsIGxvYWRgIDwtIAogIGZhY3RvcihwZXJzaXRlX25vcm0kYFZpcmFsIGxvYWRgLCAKICAgICAgICAgbGFiZWxzID0gYygiMCIsCiAgICAgICAgICAgICAgICAgICAgIjEwXnsyfSIsIAogICAgICAgICAgICAgICAgICAgICIxMF57M30iLAogICAgICAgICAgICAgICAgICAgICIxMF57NX0iKSkKCgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSHVtYW5fcmVzcGlyYXRvcnlfc3luY3l0aWFsX3ZpcnVzIikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKHggPSBzaXRlLCB5ID0gY292ZXJhZ2UsIGZpbGwgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAoVmlyYWwubG9hZCB+IFNhbXBsZV9pZCwgbGFiZWwgPSBsYWJlbF9wYXJzZWQpICsKICB5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwogIGdndGl0bGUoIkh1bWFuIFJTViAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKYGBgCgojIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3J9CiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTNS5wZGYiLHdpZHRoPTEwLGhlaWdodD04KQpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzcKYGBge3J9CgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiWmlrYV92aXJ1cyIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gc2l0ZSwgeSA9IGNvdmVyYWdlLCBmaWxsID0gQmFja2dyb3VuZCkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwogIGdndGl0bGUoIlppa2EgdmlydXMgKGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiQmFja2dyb3VuZCIpKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTNi5wZGYiLHdpZHRoPTEwLGhlaWdodD04KQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM4CmBgYHtyfQpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gc2l0ZSwgeSA9IGNvdmVyYWdlLCBmaWxsID0gQmFja2dyb3VuZCkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwogIGdndGl0bGUoIkh1bWFuIEFkZW5vdmlydXMgKGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiQmFja2dyb3VuZCIpKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTNy5wZGYiLHdpZHRoPTIwLGhlaWdodD0xOCkKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM5CmBgYHtyfQpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIikgfD4KICBnZ3Bsb3QoYWVzKHggPSBzaXRlLCB5ID0gY292ZXJhZ2UsIGZpbGwgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fcG9seWdvbigpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwogIGdndGl0bGUoIkh1bWFuIEJldGFoZXJwZXN2aXJ1cyAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKICB0aGVtZV9idygpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJQMSIsICJQMiIpKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL0hCSFZfY292ZXJhZ2VfdGVzdC5wZGYiLHdpZHRoPTIwLGhlaWdodD0xOCkKYGBgCgoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTMTAKYGBge3J9CiNoYXZlIHRvIGRvIHRoZXNlIGRpZmZlcmVudGx5IGR1ZSB0byBzZWdtZW50YXRpb24KCkZMVV9NRTEgPC0gcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKHZpcnVzID09ICJJbmZsdWVuemFfQl92aXJ1cyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDIiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwogIGdndGl0bGUoIkluZmx1ZW56YSBCIHZpcnVzIChCYWNrZ3JvdW5kIDEgZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJWaXJhbCBsb2FkIikpICsKICB0aGVtZV9idygpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHM0LAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIjFlKzAyIiwgIjFlKzAzIiwgIjFlKzA1IikpCgpGTFVfTUUyIDwtIHBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSW5mbHVlbnphX0JfdmlydXMiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgPT0gInA4IikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IHNpdGUsCiAgICB5ID0gY292ZXJhZ2UsCiAgICBmaWxsID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpCiAgKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X2dyaWQoc2VnIH4gU2FtcGxlX2lkKSArCiAgeWxhYigiTG9nKENvdmVyYWdlKSIpICsKICBnZ3RpdGxlKCJJbmZsdWVuemEgQiB2aXJ1cyAoQmFja2dyb3VuZCAyIGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIxZSswMiIsICIxZSswMyIsICIxZSswNSIpKQoKZ2dhcnJhbmdlKEZMVV9NRTEsIEZMVV9NRTIsIG5jb2wgPSAyLCBjb21tb24ubGVnZW5kID0gVFJVRSkKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTOS5wZGYiLHdpZHRoPTIwLGhlaWdodD0xOCkKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFMxMQpgYGB7cn0KClJFT19NRTEgPC0gcGVyc2l0ZV9ub3JtIHw+CmZpbHRlcih2aXJ1cyA9PSAiTWFtbWFsaWFuX29ydGhvcmVvdmlydXMzIikgfD4KZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KZmlsdGVyKEJhY2tncm91bmQgPT0gInAyIikgfD4KZ2dwbG90KGFlcygKeCA9IHNpdGUsCnkgPSBjb3ZlcmFnZSwKZmlsbCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKQopKSArCmdlb21fY29sKCkgKwpmYWNldF9ncmlkKHNlZyB+IFNhbXBsZV9pZCkgKwp5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwpnZ3RpdGxlKCJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIChCYWNrZ3JvdW5kIDEgZGVkdXBsaWNhdGVkKSIpICsKZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCnRoZW1lX2J3KCkgKwpzY2FsZV95X2xvZzEwKCkgKwpzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwKbGFiZWxzID0gYygiMWUrMDIiLCAiMWUrMDMiLCAiMWUrMDUiKSkKClJFT19NRTIgPC0gcGVyc2l0ZV9ub3JtIHw+CmZpbHRlcih2aXJ1cyA9PSAiTWFtbWFsaWFuX29ydGhvcmVvdmlydXMzIikgfD4KZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KZmlsdGVyKEJhY2tncm91bmQgPT0gInA4IikgfD4KZ2dwbG90KGFlcygKeCA9IHNpdGUsCnkgPSBjb3ZlcmFnZSwKZmlsbCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKQopKSArCmdlb21fY29sKCkgKwpmYWNldF9ncmlkKHNlZyB+IFNhbXBsZV9pZCkgKwp5bGFiKCJMb2coQ292ZXJhZ2UpIikgKwpnZ3RpdGxlKCJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIChCYWNrZ3JvdW5kIDIgZGVkdXBsaWNhdGVkKSIpICsKZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCnRoZW1lX2J3KCkgKwpzY2FsZV95X2xvZzEwKCkgKwpzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwKbGFiZWxzID0gYygiMWUrMDIiLCAiMWUrMDMiLCAiMWUrMDUiKSkKCmdnYXJyYW5nZShSRU9fTUUxLCBSRU9fTUUyLCBuY29sID0gMiwgY29tbW9uLmxlZ2VuZCA9IFRSVUUpCgojZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlc19wZGYvRmlndXJlUzEwLnBkZiIsd2lkdGg9MjAsaGVpZ2h0PTE4KQoKCmBgYAoKCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA+Pj4+IEZpZ3VyZSAzOiBhbGwgdmlydXNlcyAtIHRhcmdldCBhbmQgb2ZmIHRhcmdldAoKIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KCiMgcmVhZCBpbiBtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLCBoZWFkZXIgPSBUUlVFKQoKbWV0YWRhdGEyIDwtCiAgbWV0YWRhdGEgfD4KICBzZWxlY3QoCiAgICBTYW1wbGUuSUQsCiAgICBCYWNrZ3JvdW5kLnNhbXBsZSwKICAgIFZpcmFsLmxvYWQsCiAgICBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuCiAgKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgdmlyYWwgcmVhZHMgbWFwcGVkICh0byBjYWxjdWxhdGUgcHJvcG9ydGlvbnMpCgp2aXJhbF9yZWFkc19kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvdG90YWxfdmlydXNfbWFwcGVkX3JlYWRzX3Blcl9zYW1wbGVfZGVkdXBfYXRjY19yZWZfMjAyNDExMDguY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgp2aXJhbF9yZWFkc19ub2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS90b3RhbF92aXJ1c19tYXBwZWRfcmVhZHNfcGVyX3NhbXBsZV9ub2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA4LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKI2ltcG9ydCBjb250aW5nZW5jeSB0YWJsZXMKCmNvbnRpbmdlbmN5X2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS9jb250aW5nZW5jeV90YWJsZV9tYXBwZWRfdmlydXNfcmVhZHNfcGVyX2ZhbWlseV9nZW51c19zYW1wbGVfZGVkdXBfYXRjY19yZWZfMjAyNDExMDYuY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb250aW5nZW5jeV9ub2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS9jb250aW5nZW5jeV90YWJsZV9tYXBwZWRfdmlydXNfcmVhZHNfcGVyX2ZhbWlseV9nZW51c19zYW1wbGVfbm9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwNi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvbnRhbWluYW50cyA8LQogIGMoIkJldGFjb3JvbmF2aXJ1cyIsICJBbHBoYWluZmx1ZW56YXZpcnVzIiwgIkdhbW1hcmV0cm92aXJ1cyIpCgpgYGAKCiMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KCiMgcGl2b3QgbG9uZ2VyICAKZGVkdXBfbG9uZyA8LQogIGNvbnRpbmdlbmN5X2RlZHVwIHw+CiAgZmlsdGVyKCFnZW51cyAlaW4lIGNvbnRhbWluYW50cykgfD4KICBmaWx0ZXIoZ2VudXMgIT0gIk5BIikgfD4KICBwaXZvdF9sb25nZXIoY29scyA9IEE6UCwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiU2FtcGxlX2lkIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgfD4KICBtdXRhdGUoCiAgICB0YXJnZXQgPSBjYXNlX3doZW4oCiAgICAgIGdlbnVzID09ICJDeWNsb3ZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgZ2VudXMgPT0gIkNhcmRpb3ZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgZ2VudXMgPT0gIktvYnV2aXJ1cyIgfiAib2ZmX3RhcmdldCIsCiAgICAgIC5kZWZhdWx0ID0gIm9uX3RhcmdldCIKICAgICkKICApIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKGdlbnVzID09ICJNYXN0YWRlbm92aXJ1cyIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbnVzID09ICJDeXRvbWVnYWxvdmlydXMiKSB+ICJETkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKbm9fZGVkdXBfbG9uZyA8LSBjb250aW5nZW5jeV9ub2RlZHVwIHw+CiAgZmlsdGVyKCFnZW51cyAlaW4lIGNvbnRhbWluYW50cykgfD4KICBmaWx0ZXIoZ2VudXMgIT0gIk5BIikgfD4KICBwaXZvdF9sb25nZXIoY29scyA9IEE6UCwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiU2FtcGxlX2lkIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgfD4KICBtdXRhdGUoCiAgICB0YXJnZXQgPSBjYXNlX3doZW4oCiAgICAgIGdlbnVzID09ICJDeWNsb3ZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgZ2VudXMgPT0gIkNhcmRpb3ZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgZ2VudXMgPT0gIktvYnV2aXJ1cyIgfiAib2ZmX3RhcmdldCIsCiAgICAgIC5kZWZhdWx0ID0gIm9uX3RhcmdldCIKICAgICkKICApIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKGdlbnVzID09ICJNYXN0YWRlbm92aXJ1cyIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbnVzID09ICJDeXRvbWVnYWxvdmlydXMiKSB+ICJETkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKbWV0YWRhdGFfZGVkdXAgPC0gbGVmdF9qb2luKGRlZHVwX2xvbmcsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCmRlZHVwX3ZpcmFsX3JlYWRzIDwtCiAgbGVmdF9qb2luKG1ldGFkYXRhX2RlZHVwLCB2aXJhbF9yZWFkc19kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUodG90YWxfcmVhZHMgPSBRQ19yZWFkcyAqIDIpIHw+CiAgbXV0YXRlKHByb3BfdG90YWwgPSBjb3VudCAvIHRvdGFsX3JlYWRzKSB8PgogIG11dGF0ZShwcm9wX3ZpcmFsID0gY291bnQgLyB0b3RhbF92aXJ1c19yZWFkcykKCm1ldGFkYXRhX25vX2RlZHVwIDwtIGxlZnRfam9pbihub19kZWR1cF9sb25nLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpub2RlZHVwX3ZpcmFsX3JlYWRzIDwtCiAgbGVmdF9qb2luKG1ldGFkYXRhX25vX2RlZHVwLCB2aXJhbF9yZWFkc19ub2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKSB8PgogIG11dGF0ZSh0b3RhbF9yZWFkcyA9IFFDX3JlYWRzICogMikgfD4KICBtdXRhdGUocHJvcF90b3RhbCA9IGNvdW50IC8gdG90YWxfcmVhZHMpIHw+CiAgbXV0YXRlKHByb3BfdmlyYWwgPSBjb3VudCAvIHRvdGFsX3ZpcnVzX3JlYWRzKQoKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0KCmZhY2V0X25hbWVzIDwtIGMoCiAgIk1zcF9wMiIgPSAiUDEiLAogICJNc3BfcDgiID0gIlAyIiwKICAib2ZmX3RhcmdldCIgPSAiT2ZmIHRhcmdldCB2aXJ1c2VzIiwKICAib25fdGFyZ2V0IiA9ICJPbiB0YXJnZXQgdmlydXNlcyIKKQoKY29scyA8LQogIGMoCiAgICAiI0NDQkI0NCIsCiAgICAiIzMzMjI4OCIsCiAgICAiI0VFNzczMyIsCiAgICAiIzY2Q0NFRSIsCiAgICAiIzg4MjI1NSIsCiAgICAiIzQ0NzdBQSIsCiAgICAiI0FBMzM3NyIsCiAgICAiIzIyODgzMyIsCiAgICAiI0VFNjY3NyIKICApCgoKZGVkdXBfcmVhZHMgPC0gCiAgZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZyhjb3VudCksCiAgICBjb2xvdXIgPSBnZW51cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCh0YXJnZXQgfiBCYWNrZ3JvdW5kLnNhbXBsZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgeWxhYigiTG9nIChWaXJhbCBSZWFkcykiKSArIAogIHhsYWIoIkxvZyAoVmlyYWwgbG9hZCkiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKQoKZGVkdXBfcHJvcF92aXJhbCA8LQogIGRlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX3ZpcmFsLCBjb2xvdXIgPSBnZW51cykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCh0YXJnZXQgfiBCYWNrZ3JvdW5kLnNhbXBsZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHZpcmFsIHJlYWRzIikgKwogIHhsYWIoIkxvZyAoVmlyYWwgbG9hZCkiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApCgpkZWR1cF9wcm9wX2FsbCA8LQogIGRlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX3RvdGFsLCBjb2xvdXIgPSBnZW51cykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCh0YXJnZXQgfiBCYWNrZ3JvdW5kLnNhbXBsZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeV9sb2cxMChsaW1pdHM9Yyg1ZS04LDEpKSArCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB0b3RhbCByZWFkcyIpICsKICB4bGFiKCJMb2cgKFZpcmFsIGxvYWQpIikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogICAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKQoKYGBgCgojIyMgRGVkdXAgLS0gdmlyYWwgcmVhZHMsIHByb3AgYWxsIHJlYWRzLCBhbmQgcHJvcCB2aXJhbCByZWFkcwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTJ9CgpnZ2FycmFuZ2UoCiAgZGVkdXBfcmVhZHMsCiAgZGVkdXBfcHJvcF9hbGwsCiAgZGVkdXBfcHJvcF92aXJhbCwKICBucm93ID0gMywKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTh9CgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvdGFyZ2V0X29mZnRhcmdldF9kZWR1cC5wbmciLHdpZHRoPTgsaGVpZ2h0PTEwKQoKIyNqdXN0IHBsb3QgdmlyYWwgcmVhZHMgYW5kIHByb3AgdmlyYWwKCmdnYXJyYW5nZSgKICBkZWR1cF9yZWFkcywKICBkZWR1cF9wcm9wX3ZpcmFsLAogIG5yb3cgPSAyLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgpnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy90YXJnZXRfb2ZmdGFyZ2V0X2RlZHVwXzIwMjUtMDEtMDEucG5nIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZXNfcGRmL0ZpZ3VyZV8zXzIwMjUtMDEtMDEucGRmIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCkKCmBgYAoKIyMjIC0tLS1ub2RlZHVwIHJlc3VsdHMgLS0tLQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTZ9CiMjZXh0cmFzIC0gbm8gZGVkdXAKCm5vZGVkdXBfcmVhZHMgPC0KICBub2RlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2coY291bnQpLAogICAgY29sb3VyID0gZ2VudXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBnZW51cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQodGFyZ2V0IH4gQmFja2dyb3VuZC5zYW1wbGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeF9sb2cxMCgpICsKICB5bGFiKCJMb2coVmlyYWwgUmVhZHMpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKQoKbm9kZWR1cF9wcm9wX3ZpcmFsIDwtIAogIG5vZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfdmlyYWwsIGNvbG91ciA9IGdlbnVzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHZpcmFsIHJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKQoKbm9kZWR1cF9wcm9wX2FsbCA8LSBub2RlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX3RvdGFsLCBjb2xvdXIgPSBnZW51cykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCh0YXJnZXQgfiBCYWNrZ3JvdW5kLnNhbXBsZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV94X2xvZzEwKCkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB0b3RhbCByZWFkcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykKCmdnYXJyYW5nZSgKICBub2RlZHVwX3JlYWRzLAogIG5vZGVkdXBfcHJvcF9hbGwsCiAgbm9kZWR1cF9wcm9wX3ZpcmFsLAogIG5yb3cgPSAzLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvdGFyZ2V0X29mZnRhcmdldF9ub2RlZHVwLnBkZiIsd2lkdGg9OCxoZWlnaHQ9MTApCgpgYGAKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoK